import { ApiProperty } from "@nestjs/swagger";
import { Transform } from "class-transformer";
import { IsDate, IsOptional } from "class-validator";

import { DateTimeUtils } from "../utils/DateTimeUtils";
import { PageDto } from "./page.dto";

/**
 * 多条件查询参数，基于分页查询，多了通用的时间查询条件
 *
 * @note
 * 注意 YYYY-MM-DD HH:mm:ss 这种格式，前端可以传，MySQL 的 SQL 中也支持拼接这种格式查询。
 * 但 prisma schema 时间字段通常使用 DateTime 类型，对应的 js 类型为 Date，因此不支持字符串时间格式的查询。
 * 使用new Date() 将 string 类型要转成 Date 类型，但 nodejs 默认为 0 时区，当前服务器时区的时间字符串会转成对应的 0 时区时间
 * 如北京时间 UTC+8 2025-10-02 00:00:00，转换后会往前倒 8 小时，变成 2025-10-01T16:00:00.000Z。
 * 按理这没什么，因为表示的是绝对意义上的同一时刻。0 时区为冰岛时间。
 * 问题出在 MySQL 查询时，它不会将 0 时区自动转回本地时区东八区去查询，而是直接将 2025-10-01T16:00:00.000Z 拼接字符串。
 * 因此 MySQL 相当于拿东八区时间 2025-10-01 16:00:00 去查询，而我们想要的是东八区 2025-10-02 00:00:00 (2025-10-02T00:00:00.000Z) 去查询。
 * 因此对字符串时间字段进行转换，不能简单的用 new Date()。
 */
export class QueryDto extends PageDto {
    // @Transform(v => new Date(v.value))
    @Transform(v => {
        if (v.value instanceof Date) return v.value; // 不知道为什么 transform 会运行两次，导致重复处理
        return DateTimeUtils.parserBeijingTimeStrToDate(v.value);
    })
    @IsDate()
    @IsOptional()
    @ApiProperty({ example: "2023-09-27 10:20:30", description: "开始创建时间", required: false })
    createdAtStart: Date;

    @Transform(v => {
        if (v.value instanceof Date) return v.value;
        return DateTimeUtils.parserBeijingTimeStrToDate(v.value);
    })
    @IsDate()
    @IsOptional()
    @ApiProperty({ example: "2023-09-27 10:20:30", description: "结束创建时间", required: false })
    createdAtEnd: Date;

    @Transform(v => {
        if (v.value instanceof Date) return v.value;
        return DateTimeUtils.parserBeijingTimeStrToDate(v.value);
    })
    @IsDate()
    @IsOptional()
    @ApiProperty({ example: "2023-09-27 10:20:30", description: "开始更新时间", required: false })
    updatedAtStart: Date;

    @Transform(v => {
        if (v.value instanceof Date) return v.value;
        return DateTimeUtils.parserBeijingTimeStrToDate(v.value);
    })
    @IsDate()
    @IsOptional()
    @ApiProperty({ example: "2023-09-27 10:20:30", description: "结束更新时间", required: false })
    updatedAtEnd: Date;
}
